home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / MRCLEAN.ZIP / MRCLEAN.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-17  |  10.7 KB  |  357 lines

  1. //----------------------------------------------------------------------------
  2. // Mr.Clean v. 1.00 - (C) Copyright 1995 by Kent Reisdorph
  3. //
  4. // Novemeber 11, 1995
  5. //
  6. // mrclean.cpp - Source for Mr.Clean, an application that cleans
  7. // misc files out of Borland C++ project directories
  8. //
  9. //----------------------------------------------------------------------------
  10. #include "mrcmain.h"
  11. #pragma hdrstop
  12.  
  13. /// code for MrCleanWindow /////////////////////////////////////
  14. DEFINE_RESPONSE_TABLE1(MrCleanWindow, TWindow)
  15.     EV_COMMAND(CM_CHOOSEDIR, CmChooseDir),
  16.     EV_COMMAND(CM_XIT, CmExit),
  17.     EV_COMMAND(CM_CLEAN, CmClean),
  18.     EV_COMMAND(CM_CONFIG, CmConfig),
  19.     EV_COMMAND(CM_ABOUT, CmAbout),
  20.     EV_WM_TIMER,
  21. END_RESPONSE_TABLE;
  22.  
  23. MrCleanWindow::MrCleanWindow(const char far* _path, const char far* cmd)
  24.     : TWindow(0, 0, 0),
  25.     fData(OFN_PATHMUSTEXIST, "", 0, "", "*")
  26. {
  27.     bitmap = 0;
  28.     pal = 0;
  29.     // no mode passed
  30.     mode = -1;
  31.     // set the mode according to the string passed in the mode param
  32.     if(!strcmpi(cmd, "CONFIG")) mode = CONFIG;
  33.     if (!strcmpi(cmd, "CLEAN")) {
  34.         mode = CLEAN;
  35.         // if mode is CLEAN then make the window invisible
  36.         GetApplication()->nCmdShow = SW_HIDE;
  37.     }
  38.     strcpy(path, "");
  39.     strcpy(target, _path);
  40.     // the following code trims the filename off the command line
  41.     // path. This condition will occur if the program is set up to run
  42.     // from the Tool menu in the IDE.
  43.     if (strlen(_path) > 0) {
  44.         string s(_path);
  45.         // if a filename was passed with the path then find the last "\"
  46.         // and chop the string off there.
  47.         if (s.find_first_of(".") != NPOS)
  48.             s.remove(s.find_last_of("\\"));
  49.         // if a filename was not passed then check to be sure the user
  50.         // didn't put a "\" at the end of the path. If so, chop it off.
  51.         else if (s.find_last_of("\\") == s.length() - 1) s.remove(s.length() - 1);
  52.         // copy the string to our path variable
  53.         strcpy(path, s.c_str());
  54.         char str[256];
  55.         // get the current working directory and save it
  56.         getcwd(str, sizeof(str));
  57.         // try to change the directory to the one passed in the command line.
  58.         // If an error occurs then the path is not valid. We will inform the
  59.         // user later in EvTimer. Copy "error" to the path since it isn't any
  60.         // good to us now.
  61.         if (chdir(path) == -1) strcpy(path, "error");
  62.         // if the chdir succeeded then add a backslash onto the end of the
  63.         // path. We'll need it later.
  64.         else strcat(path, "\\");
  65.         // change the directory back to the current working directory
  66.         chdir(str);
  67.     }
  68.     // Store the path and filename of the default config file.
  69.     // First, get the module filename. This will be the path and filename
  70.     // of the application.
  71.     GetApplication()->GetModuleFileName(cfgFile, sizeof(cfgFile));
  72.     // copy the string ".CFG" where ".EXE" is: Find the end of the string
  73.     // and back up 4 characters.
  74.     memcpy(&cfgFile[strlen(cfgFile)-4], ".CFG", 4);
  75. }
  76.  
  77. MrCleanWindow::~MrCleanWindow()
  78. {
  79.     delete bitmap;
  80.     delete pal;
  81. }
  82.  
  83. void
  84. MrCleanWindow::SetupWindow()
  85. {
  86.     TWindow::SetupWindow();
  87.     if (mode != CLEAN) {
  88.         int w, h;
  89.         int sw = GetSystemMetrics(SM_CXSCREEN);
  90.         int sh = GetSystemMetrics(SM_CYSCREEN);
  91.         // the bitmap is available to registered users. It's way cool!
  92.         // read the bitmap, get a palette
  93.         // if the bitmap is not available a TXOwl exception will be
  94.         // thrown which we will catch...
  95.         try {
  96.             TDib* dib = new TDib("mrclean.bmp");
  97.             pal = new TPalette(*dib);
  98.             bitmap = new TBitmap(*dib, pal);
  99.             delete dib;
  100.             int x = GetSystemMetrics(SM_CYFRAME) * 2;
  101.             w = bitmap->Width() + x;
  102.             h = bitmap->Height() + x + GetSystemMetrics(SM_CYMENU) * 2;
  103.         }
  104.         // catch the exception. Zero the bitmap and palette pointers
  105.         // and set the window size to 75% of the screen.
  106.         catch (TXOwl) {
  107.             bitmap = 0;
  108.             pal = 0;
  109.             w = sw * .75;
  110.             h = sh * .75;
  111.         }
  112.         // move the window
  113.         Parent->MoveWindow(sw/2 - (w/2), sh/2 - (h/2), w, h);
  114.         // if a path was passed in the command line then change the
  115.         // caption to reflect the path
  116.         if (strlen(path) > 0) {
  117.             char str[256];
  118.             wsprintf(str, "Mr.Clean - %s", path);
  119.             str[strlen(str) - 1] = 0;
  120.             Parent->SetCaption(str);
  121.         }
  122.     }
  123.     // set a timer so that automatic processing can begin if necessary
  124.     SetTimer(1,1);
  125. }
  126.  
  127. void
  128. MrCleanWindow::Paint(TDC& dc, bool, TRect&)
  129. {
  130.     // if no bitmap then don't do anything
  131.     if (!bitmap) return;
  132.     // otherwise display it
  133.     TMemoryDC memdc(dc);
  134.     memdc.SelectObject(*pal);
  135.     memdc.RealizePalette();
  136.     memdc.SelectObject(*bitmap);
  137.     dc.BitBlt(0, 0, bitmap->Width(),  bitmap->Height(), memdc, 0, 0, SRCCOPY);
  138.     memdc.RestoreObjects();
  139. }
  140.  
  141. // EvTimer. Here's where we do automatic processing
  142. void
  143. MrCleanWindow::EvTimer(uint)
  144. {
  145.     // kill the timer
  146.     KillTimer(1);
  147.     // if the path was invalid then tell the user and then close the window
  148.     if (!strcmpi(path, "error")) {
  149.         MessageBox("The path entered in the command line is not a valid path.",
  150.             "Mr.Clean Error");
  151.         Destroy();
  152.         return;
  153.     }
  154.     // if the mode is clean then DoClean and close the window
  155.     // if the mode is config then call the config function
  156.     switch (mode) {
  157.         case CLEAN :
  158.             DoClean();
  159.             Destroy();
  160.             break;
  161.         case CONFIG :
  162.             CmConfig();
  163.             break;
  164.     }
  165. }
  166.  
  167. // CmChooseDir() Allows the user to change the directory to be cleaned.
  168. void
  169. MrCleanWindow::CmChooseDir()
  170. {
  171.     if (ChooseDirDialog(this, fData, IDD_CHOOSEDIR).Execute() == IDCANCEL) return;
  172.     // change the application's caption to reflect the new path
  173.     strcpy(path, fData.FileName);
  174.     strcat(path, "\\");
  175.     char str[256];
  176.     wsprintf(str, "Mr.Clean - %s", path);
  177.     str[strlen(str) - 1] = 0;
  178.     Parent->SetCaption(str);
  179. }
  180.  
  181. // close the window unconditionally
  182. void
  183. MrCleanWindow::CmExit()
  184. {
  185.     Destroy();
  186. }
  187.  
  188. // handler for the Clean Now menu item
  189. void
  190. MrCleanWindow::CmClean()
  191. {
  192.     DoClean();
  193. }
  194.  
  195. // handler for the Configure menu item. Just executes the config
  196. // dialog box.
  197. void
  198. MrCleanWindow::CmConfig()
  199. {
  200.     new ConfigDlg(this)->Execute();
  201.     // if a path exists then change the applications title to show
  202.     // the path.
  203.     if (strlen(path) > 0) {
  204.         char str[256];
  205.         wsprintf(str, "Mr.Clean - %s", path);
  206.         str[strlen(str) - 1] = 0;
  207.         Parent->SetCaption(str);
  208.     }
  209. }
  210.  
  211. // handler for the About menu item. Executes the about dialog box.
  212. void
  213. MrCleanWindow::CmAbout()
  214. {
  215.     new TCenteredDialog(this, IDD_ABOUT)->Execute();
  216. }
  217.  
  218. // DoClean(). Performs the deletion of the files.
  219. void
  220. MrCleanWindow::DoClean()
  221. {
  222.     char temp[256];
  223.     // needed for the OpenFile function
  224.     OFSTRUCT ofStruct;
  225.     // make a path and filename with the passed path
  226.     wsprintf(temp, "%smrclean.cfg", path);
  227.     // check and see if a mrclean.cfg file exists there. OpenFile with
  228.     // the OF_EXIST path will check for existance of a file. If the file
  229.     // does not exist then use the default config file.
  230.     if (OpenFile(temp, &ofStruct, OF_EXIST) == -1) strcpy(temp, cfgFile);
  231.     // open the file
  232.     ifstream infile(temp);
  233.     // something went wrong
  234.     if (!infile) {
  235.         MessageBox("Error Opening Config File", "Mr. Clean Error",
  236.             MB_OK | MB_ICONEXCLAMATION);
  237.         return;
  238.     }
  239.     // read the values from the file for the standard file format
  240.     // check boxes. Our IDs are numbered from 101 to 122.
  241.     int val;
  242.     for (int i=101;i<123;i++) {
  243.         infile >> val;
  244.         // if val is nonzero then we need to delete the files associated
  245.         // with that checkbox. We do that by loading a string resource that
  246.         // has the same ID as the checkbox. The strings contain the filespec
  247.         // associated with the checkbox. String #101 = "*.BAK", etc.
  248.         if (val) {
  249.             char str[6];
  250.             // load the string associated with i
  251.             ::Module->LoadString(i, str, sizeof(str));
  252.             // make a complete path with the path and filespec
  253.             wsprintf(temp, "%s%s", path, str);
  254.             // do the deletion
  255.             DeleteFiles(temp);
  256.         }
  257.     }
  258.     // get the "Target .EXE Only" value
  259.     infile >> val;
  260.     // if you are using CodeGuard then it will break on this function if
  261.     // the TARGET is not in the project directory. IOW, we might be trying
  262.     // to delete a file that doesn't exist. It's no problem, but CG will
  263.     // report it as a function failure.
  264.     if (val) remove(target);
  265.     int count;
  266.     char str[80];
  267.     // get the number of strings of user defined filespecs
  268.     infile >> count;
  269.     if (count) {
  270.         for(i=0;i<count;i++) {
  271.             // read a string
  272.             infile >> str;
  273.             // make a complete path
  274.             wsprintf(temp, "%s%s", path, str);
  275.             // do the deletions
  276.             DeleteFiles(temp);
  277.         }
  278.     }
  279.     // close the file
  280.     infile.close();
  281.     // tell the user that the process is done
  282.     new TimedDlg(this, IDD_TIMED, "Directory Clean Done!", 1)->Execute();
  283. }
  284.  
  285. // DeleteFiles() Does the actual deletion of the files
  286. void
  287. MrCleanWindow::DeleteFiles(const char far* fspec)
  288. {
  289.     // use the fflbk structure with findfirst and findnext to find each
  290.     // file. The DOS function remove() does not allow wildcards so we
  291.     // need to delete each file individually.
  292.     struct ffblk ffblk;
  293.     // need a flag to indicate when we're done
  294.     int done;
  295.     char str[256];
  296.     // pass the filespec to findfirst
  297.     done = findfirst(fspec, &ffblk, 0);
  298.     //  The first file to meet the filespec condition is now contained in ffblk
  299.     while (!done)
  300.     {
  301.         // make a complete path with the filename contained in the ff_name
  302.         // member of the ffblk structure
  303.         wsprintf(str, "%s%s", path, ffblk.ff_name);
  304.         // delete the file. If an access violation occured report it.
  305.         // Why? I don't really know.<g>
  306.         if (remove(str) == -1 && errno == 5) {
  307.             char temp[300];
  308.             Parent->Show(SW_NORMAL);
  309.             wsprintf(temp, "Cannot Delete\n\n%s\n\nAccess Denied", str);
  310.             MessageBox(temp, "Mr. Clean Message", MB_OK);
  311.         }
  312.         // find the next file and loop
  313.         done = findnext(&ffblk);
  314.     }
  315. }
  316.  
  317. // The application class. Pretty basic. Just a few mods to allow for
  318. // the command line arguments.
  319. class TMrCApp : public TApplication {
  320.     public:
  321.         char command[10];
  322.         char path[256];
  323.         TMrCApp(const char far* _path, const char far* cmd)
  324.             : TApplication("Mr.Clean")
  325.         {
  326.             // copy the values passed to us from OwlMain to member variables
  327.             strcpy(path, _path);
  328.             strcpy(command, cmd);
  329.         }
  330.         void InitMainWindow()
  331.         {
  332.             // Enable BWCC and Ctl3d
  333.             EnableBWCC();
  334.       EnableCtl3d();
  335.             // setup the main window. Pass the command line args to the
  336.             // MrCleanWindow constructor.
  337.             SetMainWindow(new TFrameWindow(0,
  338.                 "Mr.Clean - BC++ Project Directory Cleaner",
  339.                 new MrCleanWindow(path, command)));
  340.             // assign our menu to the frame
  341.             MainWindow->AssignMenu(MENU_1);
  342.             // assign our icon to the frame
  343.             MainWindow->SetIcon(this, ICON_1);
  344.         }
  345. };
  346.  
  347. int OwlMain(int argc, char* argv[])
  348. {
  349.     char path[256] = "";
  350.     char cmd[10] = "";
  351.     // if args are passed to us then pass them on in the TMrCApp constructor
  352.     if (argc > 1) strcpy(path, argv[1]);
  353.     if (argc > 2)    strcpy(cmd, argv[2]);
  354.     TMrCApp app(path, cmd);
  355.     return app.Run();
  356. }
  357.